######################################################################
# File: server/ma...nt/djangomudbasecommand.py     Part of DjangoMUD #
#                                                                    #
# Copyright (C) 2010, Joachim Pileborg.                              #
# All rights reserved.                                               #
#                                                                    #
# Redistribution and use in source and binary forms, with or without #
# modification, are permitted provided that the following conditions #
# are met:                                                           #
#                                                                    #
#   o Redistributions of source code must retain the above copyright #
#     notice, this list of conditions and the following disclaimer.  #
#   o Redistributions in binary form must reproduce the above        #
#     copyright notice, this list of conditions and the following    #
#     disclaimer in the documentation and/or other materials         #
#     provided with the distribution.                                #
#   o Neither the name of the author nor the names of its            #
#     contributors may be used to endorse or promote products        #
#     derived from this software without specific prior written      #
#     permission.                                                    #
#                                                                    #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             #
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        #
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           #
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS  #
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,#
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,           #
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR #
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY       #
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     #
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF #
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF    #
# SUCH DAMAGE.                                                       #
######################################################################

from optparse import make_option

from django.core.management.base import BaseCommand
from django.conf import settings

from djangomud import log
from djangomud.server.shutdown import shutdown

######################################################################

class DjangoMUDBaseCommand(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--noreload', action='store_false', dest='use_reloader',
                    default=True,
                    help='Tells Django to NOT use the auto-reloader.'),
        )

    args = None
    options = None

    def run(self, *args, **options):
        pass

    def sig_int(self, *args):
        log.critical('Received SIGINT, shutting down')
        shutdown()

    def sig_term(self, *args):
        log.critical('Received SIGTERM, shutting down')
        shutdown()

    def sig_break(self, *args):
        log.critical('Received SIGBREAK, shutting down')
        shutdown()

    def setup_signals(self):
        try:
            import signal
        except ImportError:
            log.warn("Signal module unavailable -- "
                     "not installing signal handlers")
            return

        if signal.getsignal(signal.SIGINT) == signal.default_int_handler:
            # Only handle if there isn't already a handler, e.g. for Pdb.
            signal.signal(signal.SIGINT, self.sig_int)

        signal.signal(signal.SIGTERM, self.sig_term)

        # Catch Ctrl-Break in windows
        if hasattr(signal, "SIGBREAK"):
            signal.signal(signal.SIGBREAK, self.sig_break)

    def handle(self, *args, **options):
        self.setup_signals()

        def inner_run(do_exit=True, *args, **options):
            log.info('Validating models...')
            self.validate()
            # TODO: Check for errors, and report them?
            # TODO: override the validation?

            from django.utils import translation
            translation.activate(settings.LANGUAGE_CODE)

            self.run(*args, **options)

            if do_exit:
                import sys
                sys.exit(0)

        use_reloader = options.get('use_reloader', True)
        if use_reloader:
            from django.utils import autoreload
            try:
                autoreload.main(inner_run, args, options)
            except OSError as e:
                # The autoreloader can be in a system call when CTRL-C is
                # pressed, this will cause the EINTR error we catching here
                import errno
                if e.errno != errno.EINTR:
                    raise
        else:
            self.run(False, *args, **options)

######################################################################
